package com.edooschool.webpay.entity.context;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

import com.edooschool.webpay.entity.config.WechatpayConfig;
import com.fasterxml.jackson.annotation.JsonIgnore;

/**
 *
 * @author downpour
 */
public class WechatpayContext {
    
    private static String PACKAGE_VALUE = "prepay_id=";
    
    private static String SIGN_TYPE = "MD5";
    
    /**
     * 应用ID - 微信开放平台审核通过的应用APPID
     *
     * - wx8888888888888888 (example)
     */
    private String appId;

    /**
     * 订单详情扩展字符串
     *
     * - prepay_id=***
     */
    private String packageValue;

    /**
     * 随机字符串，不长于32位
     *
     * - 5K8264ILTKCH16CQ2502SI8ZNMTM67VS (example)
     */
    private String nonceStr;

    /**
     * 时间戳,当前的时间,精确到秒
     *
     * - 1412000000   (example)
     */
    private String timestamp;
    
    /**
     * 签名算法，暂支持MD5
     *
     * - MD5   (example)
     */
    private String signType;

    /**
     * 签名
     *
     * - C380BEC2BFD727A4B6845133519F3AD6    (example)
     */
    private String paySign;


    /**
     * @param wechatpayConfig
     * @param prepayId
     */
    public WechatpayContext(WechatpayConfig wechatpayConfig, String prepayId) {
        this.timestamp = String.valueOf(System.currentTimeMillis() / 1000);   // need to convert to second instead of millsecond
        this.nonceStr = RandomStringUtils.randomNumeric(12);
        this.appId = wechatpayConfig.getAppid();
        this.packageValue = com.demo2do.core.utils.StringUtils.connect(PACKAGE_VALUE, prepayId);
        this.signType = SIGN_TYPE;
    }

    /**
     * Check whether this {@link WechatpayContext} is valid
     * @return
     */
    @JsonIgnore
    public boolean isValid() {
        return StringUtils.isNotBlank(this.appId) &&
                StringUtils.isNoneBlank(this.packageValue) &&
                !StringUtils.equalsIgnoreCase(this.packageValue, PACKAGE_VALUE);
    }

    /**
     * Make signature
     * @param sign
     * @return
     */
    public WechatpayContext sign(String sign) {
        this.paySign = sign;
        return this;
    }

    /**
     * 
     * @return
     */
    public Map<String,  String> toSignatureContext() {
        Map<String, String> result = new HashMap<String, String>();
        result.put("appId", this.appId);
        result.put("nonceStr", this.nonceStr);
        result.put("package", this.packageValue);
        result.put("signType", this.signType);
        result.put("timeStamp", this.timestamp);
        return result;
    }

    /**
     * @return the appId
     */
    public String getAppId() {
        return appId;
    }

    /**
     * @return the packageValue
     */
    public String getPackageValue() {
        return packageValue;
    }

    /**
     * @return the nonceStr
     */
    public String getNonceStr() {
        return nonceStr;
    }

    /**
     * @return the timestamp
     */
    public String getTimestamp() {
        return timestamp;
    }

    /**
     * @return the signType
     */
    public String getSignType() {
        return signType;
    }

    /**
     * @return the paySign
     */
    public String getPaySign() {
        return paySign;
    }

    /**
     * @param appId the appId to set
     */
    public void setAppId(String appId) {
        this.appId = appId;
    }

    /**
     * @param packageValue the packageValue to set
     */
    public void setPackageValue(String packageValue) {
        this.packageValue = packageValue;
    }

    /**
     * @param nonceStr the nonceStr to set
     */
    public void setNonceStr(String nonceStr) {
        this.nonceStr = nonceStr;
    }

    /**
     * @param timestamp the timestamp to set
     */
    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    /**
     * @param signType the signType to set
     */
    public void setSignType(String signType) {
        this.signType = signType;
    }

    /**
     * @param paySign the paySign to set
     */
    public void setPaySign(String paySign) {
        this.paySign = paySign;
    }
}
